package com.unproy.model.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;


@Entity
@Table(name = "TBCOMT")
public class Comment implements Serializable, Comparable<Comment>, Publishable {
	private static final long	serialVersionUID	= 2139153707272681790L;
	private Long				commentId;
	private Comment				parentComment;
	private Article				article;
	private User				createdBy;
	private Date				createdOn			= new Date();
	private Boolean				approved			= false;
	private User				approvedBy;
	private Date				approvedOn;
	private User				publishedBy;
	private Date				publishedOn;
	private String				userName;
	private String				userEmail;
	private String				userIpAddress;
	private String				commentText;
	private List<Comment>		childrenComments	= new ArrayList<Comment>();
	
	@Id
	@SequenceGenerator(name = "commentId", sequenceName = "SQCOMT")
	@GeneratedValue(generator = "commentId", strategy = GenerationType.SEQUENCE)
	@Column(name = "COMTID", unique = true, nullable = false)
	public Long getCommentId() {
		return this.commentId;
	}
	
	public void setCommentId(Long commentId) {
		this.commentId = commentId;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "PCOMID")
	public Comment getParentComment() {
		return this.parentComment;
	}
	
	public void setParentComment(Comment parentComment) {
		this.parentComment = parentComment;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "ARTCID", nullable = false)
	public Article getArticle() {
		return this.article;
	}
	
	public void setArticle(Article article) {
		this.article = article;
	}
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "CUSRID")
	@Override
	public User getCreatedBy() {
		return this.createdBy;
	}
	
	@Override
	public void setCreatedBy(User createdBy) {
		this.createdBy = createdBy;
	}
	
	@Column(name = "CRTDON", nullable = false)
	@Override
	public Date getCreatedOn() {
		return this.createdOn;
	}
	
	@Override
	public void setCreatedOn(Date createdOn) {
		this.createdOn = createdOn;
	}
	
	@Column(name = "ISAPRV", nullable = false)
	@Override
	public Boolean isApproved() {
		return this.approved;
	}
	
	@Override
	public void setApproved(Boolean approved) {
		this.approved = approved;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "AUSRID")
	@Override
	public User getApprovedBy() {
		return this.approvedBy;
	}
	
	@Override
	public void setApprovedBy(User approvedBy) {
		this.approvedBy = approvedBy;
	}
	
	@Column(name = "APRVON")
	@Override
	public Date getApprovedOn() {
		return this.approvedOn;
	}
	
	@Override
	public void setApprovedOn(Date approvedOn) {
		this.approvedOn = approvedOn;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "PUSRID")
	@Override
	public User getPublishedBy() {
		return this.publishedBy;
	}
	
	@Override
	public void setPublishedBy(User user) {
		this.publishedBy = user;
	}
	
	@Column(name = "PBSHON", nullable = false)
	@Override
	public Date getPublishedOn() {
		return this.publishedOn;
	}
	
	@Override
	public void setPublishedOn(Date publishedOn) {
		this.publishedOn = publishedOn;
	}
	
	@Column(name = "USRNAM", nullable = false)
	public String getUserName() {
		return this.userName;
	}
	
	public void setUserName(String userName) {
		this.userName = userName;
	}
	
	@Column(name = "USREML", nullable = false)
	public String getUserEmail() {
		return this.userEmail;
	}
	
	public void setUserEmail(String userEmail) {
		this.userEmail = userEmail;
	}
	
	@Column(name = "USRIPA", nullable = false)
	public String getUserIpAddress() {
		return this.userIpAddress;
	}
	
	public void setUserIpAddress(String userIpAddress) {
		this.userIpAddress = userIpAddress;
	}
	
	@Column(name = "COMTXT", nullable = false)
	public String getCommentText() {
		return this.commentText;
	}
	
	public void setCommentText(String commentText) {
		this.commentText = commentText;
	}
	
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "parentComment")
	public List<Comment> getChildrenComments() {
		return this.childrenComments;
	}
	
	public void setChildrenComments(List<Comment> childrenComments) {
		this.childrenComments = childrenComments;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((this.commentId == null) ? 0 : this.commentId.hashCode());
		result = prime * result + ((this.createdBy == null) ? 0 : this.createdBy.hashCode());
		result = prime * result + ((this.createdOn == null) ? 0 : this.createdOn.hashCode());
		result = prime * result + ((this.userName == null) ? 0 : this.userName.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Comment other = (Comment) obj;
		if (this.commentId == null) {
			if (other.commentId != null)
				return false;
		} else if (!this.commentId.equals(other.commentId))
			return false;
		if (this.createdBy == null) {
			if (other.createdBy != null)
				return false;
			else {
				if (this.userName == null) {
					if (other.userName != null)
						return false;
				} else if (!this.userName.equals(other.userName))
					return false;
			}
		} else if (!this.createdBy.equals(other.createdBy))
			return false;
		if (this.createdOn == null) {
			if (other.createdOn != null)
				return false;
		} else if (!this.createdOn.equals(other.createdOn))
			return false;
		return true;
	}
	
	@Override
	public int compareTo(Comment comment) {
		return getCreatedOn().compareTo(comment.getCreatedOn());
	}
	
	@Override
	public String toString() {
		return getCommentText();
	}
}
